/**
 * 本地json | excel文件上传解析
 */
import React from "react";
import { Upload, Button, Progress, message } from "antd";
import { UploadOutlined, DeleteOutlined } from "@ant-design/icons";
import XLSX from "xlsx";
import "./index.scss";

const JSON_SUFFIX = "json";
const XLSX_SUFFIX = "xlsx";
interface ILocalUploadProps {
  name?: string;
  onChange?: (data: any) => any;
  extensions?: { [key: string]: (file: Blob) => any; }
}
interface ILocalUploadState {
  file:  any;                             // 当前上传的文件
  status: "none" | "uploading" | "done";  // 当前上传解析的状态
}
export default class LocalUpload extends React.Component<ILocalUploadProps, ILocalUploadState> {
  constructor(props: ILocalUploadProps) {
    super(props);
    this.state = {
      file: null,
      status: "done"
    }
  }
  getFileSuffix = (filename: string) => {
    return filename.split(".").pop();
  }
  parseJsonFile = (file: Blob) => {
    const { onChange } = this.props;
    const reader = new FileReader();
    reader.readAsText(file, "UTF-8");
    reader.onload = (evt) => {
      const fileString = evt.target?.result;
      if (!fileString) return;
      try {
        const jsonData = JSON.parse((fileString as any));
        onChange && onChange(jsonData);
        this.setState({ status: "done" })
      } catch (err) {
        message.error(`当前文件解析失败，请检查json文件是否存在错误!`);
        this.setState({ file: null, status: "none" });
      }
    }
  }
  parseExcelFile = (file: Blob) => {
    const { onChange } = this.props;
    const reader = new FileReader();
    reader.onload = (evt) => {
      const data = evt.target?.result;
      const workbook = XLSX.read(data, { type: "binary" });
      const outData = XLSX.utils.sheet_to_json<any>(workbook.Sheets[workbook.SheetNames[0]]);
      const lastData = {};
      outData.forEach(item => {
        Object.keys(item).forEach(key => {
          if (key.startsWith("__")) return;
          if (!Reflect.has(lastData, key)) Reflect.set(lastData, key, []);
          (lastData as any)[key].push(item[key]);
        })
      })
      onChange && onChange(lastData);
      this.setState({ status: "done" })
    }
    reader.readAsBinaryString(file);
  }
  uploadHandler = (options: any) => {
    const { extensions, onChange } = this.props;
    const { file } = options;
    this.setState({ file, status: "uploading" });
    const suffix = this.getFileSuffix(file.name);
    switch (suffix) {
      case JSON_SUFFIX:
        this.parseJsonFile(file);
        break;
      case XLSX_SUFFIX:
        this.parseExcelFile(file);
        break;
      default:
        if (extensions && Reflect.has(extensions, (suffix as any))) {
          const parseFunc = Reflect.get(extensions, (suffix as any));
          const result = parseFunc(file);
          onChange && onChange(result);
          return;
        }
        message.warning(`文件类型无法解析，可以解析json, excel文件，当前文件类型${suffix}`);
    }
  }
  /* 删除文件上传 */
  deleteUpload = () => {
    const { onChange } = this.props;
    this.setState({ file: null, status: "none" });
    onChange && onChange(null)
  }
  render() {
    const { name } = this.props;
    const { file, status } = this.state;
    return !file ? <Upload accept=".json,.xlsx" customRequest={this.uploadHandler} showUploadList={false}>
      <Button icon={<UploadOutlined />}>
        { name || "文件导入" }
      </Button>
    </Upload> : (<div className="file-uploading-wrapper">
        <div className="upload-file-info">
          <span className="filename">{status === "done" ? file?.name : `${file?.name}上传中...`}</span>
          <DeleteOutlined className="delete-icon" onClick={() => this.deleteUpload()} />
        </div>
        { status === "uploading" && <Progress strokeColor={{ from: '#108ee9', to: '#87d068' }} percent={100} status="active" showInfo={false} />}
    </div>)
  }
}